/*******************************************************************************
  * @file                   USART.c
  * @Author:                MQjehovah                 mail:MQjehovah@hotmail.com
  * @version                1.0.0
  * @date                   2017.11.22
  * @brief                  
  ******************************************************************************
  * @attention
*******************************************************************************/
/* Includes ------------------------------------------------------------------*/
#include "USART.h"
#include "ring_buffer.h"
/* Definition ----------------------------------------------------------------*/

/* Functions -----------------------------------------------------------------*/
/*******************************************************************************
  * @brief  串口引脚配置            
  * @param  None              
  * @retval None              
  * @Note   None              
******************************************************************************/
void USART_GPIO_Config(USART_TypeDef *USARTx)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    if (USARTx == USART1)
    {
        GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_USART1);  //PA9 复用为 USART1
        GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_USART1); //PA10复用为USART1
        //USART1_TX PA.9 PA.10
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10; //GPIOA9 与 GPIOA10
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;            //复用功能
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;       //速度 50MHz
        GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;          //推挽复用输出
        GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;            //上拉
        GPIO_Init(GPIOA, &GPIO_InitStructure);                  //初始化 PA9，PA10
    }
}

/*******************************************************************************
  * @brief  串口初始化            
  * @param  None              
  * @retval None              
  * @Note   None              
*******************************************************************************/
void USART_Config(USART_TypeDef *USARTx, u32 Buand)
{
    USART_GPIO_Config(USARTx);
    // USART_DeInit(USARTx); //复位串口 1
    USART_InitTypeDef USART_InitStructure;
    USART_InitStructure.USART_BaudRate = Buand;                 //一般设置为 9600;
    USART_InitStructure.USART_WordLength = USART_WordLength_8b; //字长为 8 位数据格式
    USART_InitStructure.USART_StopBits = USART_StopBits_1;      //一个停止位
    USART_InitStructure.USART_Parity = USART_Parity_No;         //无奇偶校验位
    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
    USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //收发模式
    USART_Init(USARTx, &USART_InitStructure);                       //初始化串口
    USART_ITConfig(USARTx, USART_IT_RXNE, ENABLE);                  //开启中断
    USART_Cmd(USARTx, ENABLE);                                      //使能串口
}
/*******************************************************************************
  * @brief  串口发送一个字节              
  * @param  None              
  * @retval None              
  * @Note   None              
*******************************************************************************/
void USART_SendChar(USART_TypeDef *USARTx, char c)
{
    USART_SendData(USARTx, c);
    while (RESET == USART_GetFlagStatus(USARTx, USART_FLAG_TXE))
        ;
}
/*******************************************************************************
  * @brief  USART发送字符串
  * @param  None
  * @retval None
  * @Note   None
*******************************************************************************/
void USART_SendStr(USART_TypeDef *USARTx, char *senddata)
{
    while ('\0' != *senddata) // \0 表示字符串结束标志，通过检测是否字符串末尾
    {
        USART_SendData(USARTx, *senddata++);
        while (USART_GetFlagStatus(USARTx, USART_FLAG_TXE) == RESET)
            ;
    }
}
/*******************************************************************************
  * @brief  串口1中断函数
  * @param  None
  * @retval None
  * @Note   None
*******************************************************************************/
void USART1_IRQHandler(void)
{
    if (USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) //如果寄存器中有数据
    {
        u8 data = USART_ReceiveData(USART1);
        // Parser(data);
        RingBuf_write(data);
    }
    if (USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
    {
        USART_ClearITPendingBit(USART1, USART_IT_TC);
    }
}

/*******************************************************************************
  * @brief  打印数字，带进制转换
  * @param  None
  * @retval None
  * @Note   None
*******************************************************************************/
void printNumber(USART_TypeDef *USARTx, unsigned long n, u8 base)
{
    unsigned char buf[8 * sizeof(long)]; // Assumes 8-bit chars.
    unsigned long i = 0;

    if (n == 0)
    {
        USART_SendChar(USARTx, '0');
        return;
    }

    while (n > 0)
    {
        buf[i++] = n % base;
        n /= base;
    }

    for (; i > 0; i--)
        USART_SendChar(USARTx, (char)(buf[i - 1] < 10 ? '0' + buf[i - 1] : 'A' + buf[i - 1] - 10));
}

//不使用半主机模式
#if 1 //如果没有这段，则需要在target选项中选择使用USE microLIB
#pragma import(__use_no_semihosting)
struct __FILE
{
    int handle;
};
FILE __stdout;

void _sys_exit(int x)
{
    x = x;
}
#endif
#ifdef __GNUC__
/* With GCC/RAISONANCE, small printf (option LD Linker->Libraries->Small printf
    set to 'Yes') calls __io_putchar() */
int _write(int fd, char *pBuffer, int size)
{
    for (int i = 0; i < size; i++)
    {
        USART_SendData(Debug_USART, pBuffer[i]);
        while (USART_GetFlagStatus(Debug_USART, USART_FLAG_TXE) == RESET)
            ;
    }
    return size;
}
#else
int fputc(int ch, FILE *f)
{
    /* Place your implementation of fputc here */
    /* e.g. write a character to the USART */
    USART_SendData(Debug_USART, ch);
    /* Loop until the end of transmission */
    while (USART_GetFlagStatus(Debug_USART, USART_FLAG_TXE) == RESET)
        ;
    return ch;
}
#endif /* __GNUC__ */
/*********************************END OF FILE**********************************/
